import {
  elementChildren,
  elementOffset,
  elementParents,
  getTranslate
} from '../../components/shared/utils'

export default function Zoom({ swiper, extendParams, on, emit }) {
  extendParams({
    zoom: {
      enabled: false,
      limitToOriginalSize: false,
      maxRatio: 3,
      minRatio: 1,
      toggle: true,
      containerClass: 'swiper-zoom-container',
      zoomedSlideClass: 'swiper-slide-zoomed'
    }
  })

  swiper.zoom = {
    enabled: false
  }

  let currentScale = 1
  let isScaling = false
  let fakeGestureTouched
  let fakeGestureMoved
  const evCache = []
  const gesture = {
    originX: 0,
    originY: 0,
    slideEl: undefined,
    slideWidth: undefined,
    slideHeight: undefined,
    imageEl: undefined,
    imageWrapEl: undefined,
    maxRatio: 3
  }
  const image = {
    isTouched: undefined,
    isMoved: undefined,
    currentX: undefined,
    currentY: undefined,
    minX: undefined,
    minY: undefined,
    maxX: undefined,
    maxY: undefined,
    width: undefined,
    height: undefined,
    startX: undefined,
    startY: undefined,
    touchesStart: {},
    touchesCurrent: {}
  }
  const velocity = {
    x: undefined,
    y: undefined,
    prevPositionX: undefined,
    prevPositionY: undefined,
    prevTime: undefined
  }

  let scale = 1
  Object.defineProperty(swiper.zoom, 'scale', {
    get() {
      return scale
    },
    set(value) {
      if (scale !== value) {
        const { imageEl } = gesture
        const { slideEl } = gesture
        emit('zoomChange', value, imageEl, slideEl)
      }
      scale = value
    }
  })

  function getDistanceBetweenTouches() {
    if (evCache.length < 2) return 1
    const x1 = evCache[0].pageX
    const y1 = evCache[0].pageY
    const x2 = evCache[1].pageX
    const y2 = evCache[1].pageY
    const distance = Math.sqrt((x2 - x1) ** 2 + (y2 - y1) ** 2)
    return distance
  }

  function getMaxRatio() {
    const params = swiper.params.zoom
    const maxRatio =
      gesture.imageWrapEl.getAttribute('data-swiper-zoom') || params.maxRatio
    if (
      params.limitToOriginalSize &&
      gesture.imageEl &&
      gesture.imageEl.naturalWidth
    ) {
      const imageMaxRatio =
        gesture.imageEl.naturalWidth / gesture.imageEl.offsetWidth
      return Math.min(imageMaxRatio, maxRatio)
    }
    return maxRatio
  }

  function getScaleOrigin() {
    if (evCache.length < 2)
      return {
        x: null,
        y: null
      }
    const box = gesture.imageEl.getBoundingClientRect()
    return [
      (evCache[0].pageX +
        (evCache[1].pageX - evCache[0].pageX) / 2 -
        box.x -
        window.scrollX) /
        currentScale,

      (evCache[0].pageY +
        (evCache[1].pageY - evCache[0].pageY) / 2 -
        box.y -
        window.scrollY) /
        currentScale
    ]
  }

  function getSlideSelector() {
    return swiper.isElement ? `swiper-slide` : `.${swiper.params.slideClass}`
  }

  function eventWithinSlide(e) {
    const slideSelector = getSlideSelector()
    if (e.target.matches(slideSelector)) return true
    if (
      swiper.slides.filter((slideEl) => slideEl.contains(e.target)).length > 0
    )
      return true
    return false
  }

  function eventWithinZoomContainer(e) {
    const selector = `.${swiper.params.zoom.containerClass}`
    if (e.target.matches(selector)) return true
    if (
      [...swiper.hostEl.querySelectorAll(selector)].filter((containerEl) =>
        containerEl.contains(e.target)
      ).length > 0
    )
      return true
    return false
  }

  // Events
  function onGestureStart(e) {
    if (e.pointerType === 'mouse') {
      evCache.splice(0, evCache.length)
    }
    if (!eventWithinSlide(e)) return
    const params = swiper.params.zoom
    fakeGestureTouched = false
    fakeGestureMoved = false
    evCache.push(e)
    if (evCache.length < 2) {
      return
    }
    fakeGestureTouched = true
    gesture.scaleStart = getDistanceBetweenTouches()

    if (!gesture.slideEl) {
      gesture.slideEl = e.target.closest(
        `.${swiper.params.slideClass}, swiper-slide`
      )
      if (!gesture.slideEl) gesture.slideEl = swiper.slides[swiper.activeIndex]

      let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`)
      if (imageEl) {
        imageEl = imageEl.querySelectorAll(
          'picture, img, svg, canvas, .swiper-zoom-target'
        )[0]
      }
      gesture.imageEl = imageEl
      if (imageEl) {
        gesture.imageWrapEl = elementParents(
          gesture.imageEl,
          `.${params.containerClass}`
        )[0]
      } else {
        gesture.imageWrapEl = undefined
      }

      if (!gesture.imageWrapEl) {
        gesture.imageEl = undefined
        return
      }

      gesture.maxRatio = getMaxRatio()
    }
    if (gesture.imageEl) {
      const [originX, originY] = getScaleOrigin()
      gesture.originX = originX
      gesture.originY = originY
      gesture.imageEl.style.transitionDuration = '0ms'
    }
    isScaling = true
  }

  function onGestureChange(e) {
    if (!eventWithinSlide(e)) return
    const params = swiper.params.zoom
    const { zoom } = swiper
    const pointerIndex = evCache.findIndex(
      (cachedEv) => cachedEv.pointerId === e.pointerId
    )
    if (pointerIndex >= 0) evCache[pointerIndex] = e

    if (evCache.length < 2) {
      return
    }
    fakeGestureMoved = true
    gesture.scaleMove = getDistanceBetweenTouches()

    if (!gesture.imageEl) {
      return
    }

    zoom.scale = (gesture.scaleMove / gesture.scaleStart) * currentScale
    if (zoom.scale > gesture.maxRatio) {
      zoom.scale =
        gesture.maxRatio - 1 + (zoom.scale - gesture.maxRatio + 1) ** 0.5
    }
    if (zoom.scale < params.minRatio) {
      zoom.scale =
        params.minRatio + 1 - (params.minRatio - zoom.scale + 1) ** 0.5
    }
    gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`
  }

  function onGestureEnd(e) {
    if (!eventWithinSlide(e)) return
    if (e.pointerType === 'mouse' && e.type === 'pointerout') return

    const params = swiper.params.zoom
    const { zoom } = swiper
    const pointerIndex = evCache.findIndex(
      (cachedEv) => cachedEv.pointerId === e.pointerId
    )
    if (pointerIndex >= 0) evCache.splice(pointerIndex, 1)

    if (!fakeGestureTouched || !fakeGestureMoved) {
      return
    }

    fakeGestureTouched = false
    fakeGestureMoved = false
    if (!gesture.imageEl) return

    zoom.scale = Math.max(
      Math.min(zoom.scale, gesture.maxRatio),
      params.minRatio
    )
    gesture.imageEl.style.transitionDuration = `${swiper.params.speed}ms`
    gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`
    currentScale = zoom.scale
    isScaling = false
    if (zoom.scale > 1 && gesture.slideEl) {
      gesture.slideEl.classList.add(`${params.zoomedSlideClass}`)
    } else if (zoom.scale <= 1 && gesture.slideEl) {
      gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`)
    }
    if (zoom.scale === 1) {
      gesture.originX = 0
      gesture.originY = 0
      gesture.slideEl = undefined
    }
  }
  let allowTouchMoveTimeout

  function allowTouchMove() {
    swiper.touchEventsData.preventTouchMoveFromPointerMove = false
  }

  function preventTouchMove() {
    clearTimeout(allowTouchMoveTimeout)
    swiper.touchEventsData.preventTouchMoveFromPointerMove = true
    allowTouchMoveTimeout = setTimeout(() => {
      if (swiper.destroyed) return
      allowTouchMove()
    })
  }

  function onTouchStart(e) {
    const { device } = swiper
    if (!gesture.imageEl) return
    if (image.isTouched) return
    if (device.android && e.cancelable) e.preventDefault()
    image.isTouched = true
    const event = evCache.length > 0 ? evCache[0] : e
    image.touchesStart.x = event.pageX
    image.touchesStart.y = event.pageY
  }

  function onTouchMove(e) {
    if (!eventWithinSlide(e) || !eventWithinZoomContainer(e)) {
      return
    }
    const { zoom } = swiper
    if (!gesture.imageEl) {
      return
    }
    if (!image.isTouched || !gesture.slideEl) {
      return
    }
    if (!image.isMoved) {
      image.width = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth
      image.height =
        gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight
      image.startX = getTranslate(gesture.imageWrapEl, 'x') || 0
      image.startY = getTranslate(gesture.imageWrapEl, 'y') || 0
      gesture.slideWidth = gesture.slideEl.offsetWidth
      gesture.slideHeight = gesture.slideEl.offsetHeight
      gesture.imageWrapEl.style.transitionDuration = '0ms'
    }
    // Define if we need image drag
    const scaledWidth = image.width * zoom.scale
    const scaledHeight = image.height * zoom.scale

    image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0)
    image.maxX = -image.minX
    image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0)
    image.maxY = -image.minY

    image.touchesCurrent.x = evCache.length > 0 ? evCache[0].pageX : e.pageX
    image.touchesCurrent.y = evCache.length > 0 ? evCache[0].pageY : e.pageY
    const touchesDiff = Math.max(
      Math.abs(image.touchesCurrent.x - image.touchesStart.x),
      Math.abs(image.touchesCurrent.y - image.touchesStart.y)
    )
    if (touchesDiff > 5) {
      swiper.allowClick = false
    }

    if (!image.isMoved && !isScaling) {
      if (
        swiper.isHorizontal() &&
        ((Math.floor(image.minX) === Math.floor(image.startX) &&
          image.touchesCurrent.x < image.touchesStart.x) ||
          (Math.floor(image.maxX) === Math.floor(image.startX) &&
            image.touchesCurrent.x > image.touchesStart.x))
      ) {
        image.isTouched = false
        allowTouchMove()
        return
      }
      if (
        !swiper.isHorizontal() &&
        ((Math.floor(image.minY) === Math.floor(image.startY) &&
          image.touchesCurrent.y < image.touchesStart.y) ||
          (Math.floor(image.maxY) === Math.floor(image.startY) &&
            image.touchesCurrent.y > image.touchesStart.y))
      ) {
        image.isTouched = false
        allowTouchMove()
        return
      }
    }
    if (e.cancelable) {
      e.preventDefault()
    }
    e.stopPropagation()
    preventTouchMove()

    image.isMoved = true
    const scaleRatio =
      (zoom.scale - currentScale) /
      (gesture.maxRatio - swiper.params.zoom.minRatio)
    const { originX, originY } = gesture

    image.currentX =
      image.touchesCurrent.x -
      image.touchesStart.x +
      image.startX +
      scaleRatio * (image.width - originX * 2)
    image.currentY =
      image.touchesCurrent.y -
      image.touchesStart.y +
      image.startY +
      scaleRatio * (image.height - originY * 2)

    if (image.currentX < image.minX) {
      image.currentX = image.minX + 1 - (image.minX - image.currentX + 1) ** 0.8
    }
    if (image.currentX > image.maxX) {
      image.currentX = image.maxX - 1 + (image.currentX - image.maxX + 1) ** 0.8
    }

    if (image.currentY < image.minY) {
      image.currentY = image.minY + 1 - (image.minY - image.currentY + 1) ** 0.8
    }
    if (image.currentY > image.maxY) {
      image.currentY = image.maxY - 1 + (image.currentY - image.maxY + 1) ** 0.8
    }

    // Velocity
    if (!velocity.prevPositionX) velocity.prevPositionX = image.touchesCurrent.x
    if (!velocity.prevPositionY) velocity.prevPositionY = image.touchesCurrent.y
    if (!velocity.prevTime) velocity.prevTime = Date.now()
    velocity.x =
      (image.touchesCurrent.x - velocity.prevPositionX) /
      (Date.now() - velocity.prevTime) /
      2
    velocity.y =
      (image.touchesCurrent.y - velocity.prevPositionY) /
      (Date.now() - velocity.prevTime) /
      2
    if (Math.abs(image.touchesCurrent.x - velocity.prevPositionX) < 2)
      velocity.x = 0
    if (Math.abs(image.touchesCurrent.y - velocity.prevPositionY) < 2)
      velocity.y = 0
    velocity.prevPositionX = image.touchesCurrent.x
    velocity.prevPositionY = image.touchesCurrent.y
    velocity.prevTime = Date.now()

    gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`
  }

  function onTouchEnd() {
    const { zoom } = swiper
    if (!gesture.imageEl) return
    if (!image.isTouched || !image.isMoved) {
      image.isTouched = false
      image.isMoved = false
      return
    }
    image.isTouched = false
    image.isMoved = false
    let momentumDurationX = 300
    let momentumDurationY = 300
    const momentumDistanceX = velocity.x * momentumDurationX
    const newPositionX = image.currentX + momentumDistanceX
    const momentumDistanceY = velocity.y * momentumDurationY
    const newPositionY = image.currentY + momentumDistanceY

    // Fix duration
    if (velocity.x !== 0)
      momentumDurationX = Math.abs((newPositionX - image.currentX) / velocity.x)
    if (velocity.y !== 0)
      momentumDurationY = Math.abs((newPositionY - image.currentY) / velocity.y)
    const momentumDuration = Math.max(momentumDurationX, momentumDurationY)

    image.currentX = newPositionX
    image.currentY = newPositionY
    // Define if we need image drag
    const scaledWidth = image.width * zoom.scale
    const scaledHeight = image.height * zoom.scale
    image.minX = Math.min(gesture.slideWidth / 2 - scaledWidth / 2, 0)
    image.maxX = -image.minX
    image.minY = Math.min(gesture.slideHeight / 2 - scaledHeight / 2, 0)
    image.maxY = -image.minY
    image.currentX = Math.max(Math.min(image.currentX, image.maxX), image.minX)
    image.currentY = Math.max(Math.min(image.currentY, image.maxY), image.minY)

    gesture.imageWrapEl.style.transitionDuration = `${momentumDuration}ms`
    gesture.imageWrapEl.style.transform = `translate3d(${image.currentX}px, ${image.currentY}px,0)`
  }

  function onTransitionEnd() {
    const { zoom } = swiper
    if (
      gesture.slideEl &&
      swiper.activeIndex !== swiper.slides.indexOf(gesture.slideEl)
    ) {
      if (gesture.imageEl) {
        gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)'
      }
      if (gesture.imageWrapEl) {
        gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)'
      }
      gesture.slideEl.classList.remove(`${swiper.params.zoom.zoomedSlideClass}`)

      zoom.scale = 1
      currentScale = 1
      gesture.slideEl = undefined
      gesture.imageEl = undefined
      gesture.imageWrapEl = undefined
      gesture.originX = 0
      gesture.originY = 0
    }
  }

  function zoomIn(e) {
    const { zoom } = swiper
    const params = swiper.params.zoom

    if (!gesture.slideEl) {
      if (e && e.target) {
        gesture.slideEl = e.target.closest(
          `.${swiper.params.slideClass}, swiper-slide`
        )
      }
      if (!gesture.slideEl) {
        if (
          swiper.params.virtual &&
          swiper.params.virtual.enabled &&
          swiper.virtual
        ) {
          gesture.slideEl = elementChildren(
            swiper.slidesEl,
            `.${swiper.params.slideActiveClass}`
          )[0]
        } else {
          gesture.slideEl = swiper.slides[swiper.activeIndex]
        }
      }
      let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`)
      if (imageEl) {
        imageEl = imageEl.querySelectorAll(
          'picture, img, svg, canvas, .swiper-zoom-target'
        )[0]
      }
      gesture.imageEl = imageEl
      if (imageEl) {
        gesture.imageWrapEl = elementParents(
          gesture.imageEl,
          `.${params.containerClass}`
        )[0]
      } else {
        gesture.imageWrapEl = undefined
      }
    }
    if (!gesture.imageEl || !gesture.imageWrapEl) return
    if (swiper.params.cssMode) {
      swiper.wrapperEl.style.overflow = 'hidden'
      swiper.wrapperEl.style.touchAction = 'none'
    }

    gesture.slideEl.classList.add(`${params.zoomedSlideClass}`)

    let touchX
    let touchY
    let offsetX
    let offsetY
    let diffX
    let diffY
    let translateX
    let translateY
    let imageWidth
    let imageHeight
    let scaledWidth
    let scaledHeight
    let translateMinX
    let translateMinY
    let translateMaxX
    let translateMaxY
    let slideWidth
    let slideHeight

    if (typeof image.touchesStart.x === 'undefined' && e) {
      touchX = e.pageX
      touchY = e.pageY
    } else {
      touchX = image.touchesStart.x
      touchY = image.touchesStart.y
    }

    const forceZoomRatio = typeof e === 'number' ? e : null
    if (currentScale === 1 && forceZoomRatio) {
      touchX = undefined
      touchY = undefined
      image.touchesStart.x = undefined
      image.touchesStart.y = undefined
    }

    const maxRatio = getMaxRatio()
    zoom.scale = forceZoomRatio || maxRatio
    currentScale = forceZoomRatio || maxRatio

    if (e && !(currentScale === 1 && forceZoomRatio)) {
      slideWidth = gesture.slideEl.offsetWidth
      slideHeight = gesture.slideEl.offsetHeight
      offsetX = elementOffset(gesture.slideEl).left + window.scrollX
      offsetY = elementOffset(gesture.slideEl).top + window.scrollY
      diffX = offsetX + slideWidth / 2 - touchX
      diffY = offsetY + slideHeight / 2 - touchY

      imageWidth = gesture.imageEl.offsetWidth || gesture.imageEl.clientWidth
      imageHeight = gesture.imageEl.offsetHeight || gesture.imageEl.clientHeight
      scaledWidth = imageWidth * zoom.scale
      scaledHeight = imageHeight * zoom.scale

      translateMinX = Math.min(slideWidth / 2 - scaledWidth / 2, 0)
      translateMinY = Math.min(slideHeight / 2 - scaledHeight / 2, 0)
      translateMaxX = -translateMinX
      translateMaxY = -translateMinY

      translateX = diffX * zoom.scale
      translateY = diffY * zoom.scale

      if (translateX < translateMinX) {
        translateX = translateMinX
      }
      if (translateX > translateMaxX) {
        translateX = translateMaxX
      }

      if (translateY < translateMinY) {
        translateY = translateMinY
      }
      if (translateY > translateMaxY) {
        translateY = translateMaxY
      }
    } else {
      translateX = 0
      translateY = 0
    }
    if (forceZoomRatio && zoom.scale === 1) {
      gesture.originX = 0
      gesture.originY = 0
    }
    gesture.imageWrapEl.style.transitionDuration = '300ms'
    gesture.imageWrapEl.style.transform = `translate3d(${translateX}px, ${translateY}px,0)`
    gesture.imageEl.style.transitionDuration = '300ms'
    gesture.imageEl.style.transform = `translate3d(0,0,0) scale(${zoom.scale})`
  }

  function zoomOut() {
    const { zoom } = swiper
    const params = swiper.params.zoom

    if (!gesture.slideEl) {
      if (
        swiper.params.virtual &&
        swiper.params.virtual.enabled &&
        swiper.virtual
      ) {
        gesture.slideEl = elementChildren(
          swiper.slidesEl,
          `.${swiper.params.slideActiveClass}`
        )[0]
      } else {
        gesture.slideEl = swiper.slides[swiper.activeIndex]
      }
      let imageEl = gesture.slideEl.querySelector(`.${params.containerClass}`)
      if (imageEl) {
        imageEl = imageEl.querySelectorAll(
          'picture, img, svg, canvas, .swiper-zoom-target'
        )[0]
      }
      gesture.imageEl = imageEl
      if (imageEl) {
        gesture.imageWrapEl = elementParents(
          gesture.imageEl,
          `.${params.containerClass}`
        )[0]
      } else {
        gesture.imageWrapEl = undefined
      }
    }
    if (!gesture.imageEl || !gesture.imageWrapEl) return
    if (swiper.params.cssMode) {
      swiper.wrapperEl.style.overflow = ''
      swiper.wrapperEl.style.touchAction = ''
    }
    zoom.scale = 1
    currentScale = 1
    image.touchesStart.x = undefined
    image.touchesStart.y = undefined
    gesture.imageWrapEl.style.transitionDuration = '300ms'
    gesture.imageWrapEl.style.transform = 'translate3d(0,0,0)'
    gesture.imageEl.style.transitionDuration = '300ms'
    gesture.imageEl.style.transform = 'translate3d(0,0,0) scale(1)'

    gesture.slideEl.classList.remove(`${params.zoomedSlideClass}`)
    gesture.slideEl = undefined
    gesture.originX = 0
    gesture.originY = 0
  }

  // Toggle Zoom
  function zoomToggle(e) {
    const { zoom } = swiper

    if (zoom.scale && zoom.scale !== 1) {
      // Zoom Out
      zoomOut()
    } else {
      // Zoom In
      zoomIn(e)
    }
  }

  function getListeners() {
    const passiveListener = swiper.params.passiveListeners
      ? {
          passive: true,
          capture: false
        }
      : false
    const activeListenerWithCapture = swiper.params.passiveListeners
      ? {
          passive: false,
          capture: true
        }
      : true
    return {
      passiveListener,
      activeListenerWithCapture
    }
  }

  // Attach/Detach Events
  function enable() {
    const { zoom } = swiper
    if (zoom.enabled) return
    zoom.enabled = true
    const { passiveListener, activeListenerWithCapture } = getListeners()

    // Scale image
    swiper.wrapperEl.addEventListener(
      'pointerdown',
      onGestureStart,
      passiveListener
    )
    swiper.wrapperEl.addEventListener(
      'pointermove',
      onGestureChange,
      activeListenerWithCapture
    )
    ;['pointerup', 'pointercancel', 'pointerout'].forEach((eventName) => {
      swiper.wrapperEl.addEventListener(
        eventName,
        onGestureEnd,
        passiveListener
      )
    })

    // Move image
    swiper.wrapperEl.addEventListener(
      'pointermove',
      onTouchMove,
      activeListenerWithCapture
    )
  }

  function disable() {
    const { zoom } = swiper
    if (!zoom.enabled) return
    zoom.enabled = false

    const { passiveListener, activeListenerWithCapture } = getListeners()

    // Scale image
    swiper.wrapperEl.removeEventListener(
      'pointerdown',
      onGestureStart,
      passiveListener
    )
    swiper.wrapperEl.removeEventListener(
      'pointermove',
      onGestureChange,
      activeListenerWithCapture
    )
    ;['pointerup', 'pointercancel', 'pointerout'].forEach((eventName) => {
      swiper.wrapperEl.removeEventListener(
        eventName,
        onGestureEnd,
        passiveListener
      )
    })

    // Move image
    swiper.wrapperEl.removeEventListener(
      'pointermove',
      onTouchMove,
      activeListenerWithCapture
    )
  }

  on('init', () => {
    if (swiper.params.zoom.enabled) {
      enable()
    }
  })
  on('destroy', () => {
    disable()
  })
  on('touchStart', (_s, e) => {
    if (!swiper.zoom.enabled) return
    onTouchStart(e)
  })
  on('touchEnd', (_s, e) => {
    if (!swiper.zoom.enabled) return
    onTouchEnd(e)
  })
  on('doubleTap', (_s, e) => {
    if (
      !swiper.animating &&
      swiper.params.zoom.enabled &&
      swiper.zoom.enabled &&
      swiper.params.zoom.toggle
    ) {
      zoomToggle(e)
    }
  })
  on('transitionEnd', () => {
    if (swiper.zoom.enabled && swiper.params.zoom.enabled) {
      onTransitionEnd()
    }
  })
  on('slideChange', () => {
    if (
      swiper.zoom.enabled &&
      swiper.params.zoom.enabled &&
      swiper.params.cssMode
    ) {
      onTransitionEnd()
    }
  })

  Object.assign(swiper.zoom, {
    enable,
    disable,
    in: zoomIn,
    out: zoomOut,
    toggle: zoomToggle
  })
}
